﻿#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
// 原题连接：https://leetcode.cn/problems/guess-number-higher-or-lower/
/*
题目描述：
猜数字游戏的规则如下：
每轮游戏，我都会从 1 到 n 随机选择一个数字。 请你猜选出的是哪个数字。
如果你猜错了，我会告诉你，你猜测的数字比我选出的数字是大了还是小了。
你可以通过调用一个预先定义好的接口 int guess(int num) 来获取猜测结果，返回值一共有 3 种可能的情况（-1，1 或 0）：

-1：我选出的数字比你猜的数字小 pick < num
1：我选出的数字比你猜的数字大 pick > num
0：我选出的数字和你猜的数字一样。恭喜！你猜对了！pick == num
返回我选出的数字。

示例 1：
输入：n = 10, pick = 6
输出：6

示例 2：
输入：n = 1, pick = 1
输出：1

示例 3：
输入：n = 2, pick = 1
输出：1

示例 4：
输入：n = 2, pick = 2
输出：2
 
提示：
1 <= n <= 2^31 - 1
1 <= pick <= n
*/

// 方法——二分查找
/*
思路：
由题目描述，我们可知
当guess[mid] < 0时，说明我们所猜的数字要比pick大，所以范围要缩小，执行right = mid - 1；
当guess[mid] > 0时，说明我们所猜的数字要比pick小，所以范围要扩大，执行left = mid + 1；
当guess[mid] == 0时，说明mid就等于pick了，直接返回mid即可。
当left 与right重合时跳出循环时，直接返回left即可。
*/

// 有了以上思路，那我们写起代码来也就水到渠成了：
int guessNumber(int n) {
    int left = 0;
    int right = n;
    int mid = 0;
    while (left < right) {
        mid = left + ((right - left) >> 1);
        if (guess(mid) < 0) {
            right = mid - 1;
        }
        else if (guess(mid) > 0) {
            left = mid + 1;
        }
        else {
            return mid;
        }
    }
    return left;
}
// 时间复杂度：O(logn)。
// 空间复杂度：O(1)，我们只需要用到常数级的额外空间。